using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using Pixysoft.Framework.Verifications;



namespace Pixysoft.Framework.XSchEmA.Entity
{
    /// <summary>
    /// unique schema
    /// </summary>
    public class UniqueSchema : IConstraintSchema
    {
        private string indexName;
        private string constraintName;
        private string tableName;
        private List<string> columnNames = new List<string>();

        /// <summary>
        /// index name
        /// </summary>
        [XmlIgnore]
        public string IndexName
        {
            get { return indexName; }
            set { indexName = value; }
        }
        /// <summary>
        /// constraint name
        /// </summary>
        [XmlAttribute]
        public string ConsName
        {
            get { return constraintName; }
            set { constraintName = value; }
        }
        /// <summary>
        /// table name
        /// </summary>
        [XmlAttribute]
        public string TableName
        {
            get { return tableName; }
            set { tableName = value; }
        }
        [XmlArray]
        public List<string> ColumnNames
        {
            get { return columnNames; }
            set { columnNames = value; }
        }


        TableSchema table;
        List<ColumnSchema> columns = new List<ColumnSchema>();

        /// <summary>
        /// table
        /// </summary>
        [XmlIgnore]
        public TableSchema Table
        {
            get { return table; }
            set { table = value; }
        }
        /// <summary>
        /// columns
        /// </summary>
        [XmlIgnore]
        public List<ColumnSchema> Columns
        {
            get { return columns; }
            set { columns = value; }
        }

        /// <summary>
        /// unique schema
        /// </summary>
        public UniqueSchema()
        {
        }
        /// <summary>
        /// unique schema
        /// </summary>
        /// <param name="constraintName"></param>
        /// <param name="tableName"></param>
        /// <param name="columnNames"></param>
        public UniqueSchema(string constraintName, string tableName, params string[] columnNames)
            : this(constraintName, tableName, SchemaUtility.ObjectToList<string>(columnNames))
        {
        }
        /// <summary>
        /// unique schema
        /// </summary>
        /// <param name="constraintName"></param>
        /// <param name="table"></param>
        /// <param name="columns"></param>
        public UniqueSchema(string constraintName, TableSchema table, params ColumnSchema[] columns)
            : this(constraintName, table, SchemaUtility.ObjectToList<ColumnSchema>(columns))
        {
        }
        /// <summary>
        /// unique schema
        /// </summary>
        /// <param name="constraintName"></param>
        /// <param name="tableName"></param>
        /// <param name="columnNames"></param>
        public UniqueSchema(string constraintName, string tableName, List<string> columnNames)
        {
            if (columnNames == null || columnNames.Contains(null))
                throw new Exception("006001");

            this.constraintName = constraintName;

            this.tableName = tableName;

            this.columnNames = new List<string>();

            foreach (string columnName in columnNames)
                this.columnNames.Add(columnName.ToUpper().Trim());
        }
        /// <summary>
        /// unique schema
        /// </summary>
        /// <param name="constraintName"></param>
        /// <param name="table"></param>
        /// <param name="columns"></param>
        public UniqueSchema(string constraintName, TableSchema table, List<ColumnSchema> columns)
        {
            if (table == null)
                throw new Exception("006002");

            if (columns == null || columns.Count == 0)
                throw new Exception("006003");


            this.constraintName = constraintName;

            this.table = table;

            this.tableName = table.TableName;

            this.columns = columns;

            this.columnNames = new List<string>();

            foreach (ColumnSchema column in columns)
                this.columnNames.Add(column.ColumnName);
        }
        /// <summary>
        /// check schema
        /// </summary>
        public void Inspection()
        {
            if (!Verification.Verifies(constraintName, tableName).IsNotNullOrEmpty().Result())
                throw new Exception("006004");

            if (table == null)
                throw new Exception("006005");


            if (columnNames == null || columnNames.Count == 0)
                throw new Exception("006006");

            if (columns == null || columns.Count == 0)
                throw new Exception("006007");

            if (columns.Count != columnNames.Count)
                throw new Exception("006008");

            constraintName = constraintName.ToUpper().Trim();

            TableName = TableName.ToUpper().Trim();

        }
        /// <summary>
        /// refresh schema by pointer
        /// </summary>
        public void Refresh()
        {
            if (table == null)
                throw new Exception("006009");

            if (columns == null)
                throw new Exception("006010");

            TableName = table.TableName;

            columnNames = new List<string>();

            foreach (ColumnSchema column in columns)
                ColumnNames.Add(column.ColumnName);
        }

        /// <summary>
        /// to string
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            StringBuilder builder = new StringBuilder();
            builder.Append(tableName + ":");
            builder.Append(SchemaUtility.ListToString<string>(columnNames));
            return builder.ToString();
        }
        /// <summary>
        /// clone
        /// </summary>
        /// <returns></returns>
        public UniqueSchema Clone()
        {
            return new UniqueSchema(constraintName, TableName, columnNames);

        }
    }
}
